#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include<setting.h>
#include<use_displayer.h>
#include<math.h>
#include<time.h>
#include <QMainWindow>
#include<QDebug>
#include<QMap>
#include<QVector>
#include<QList>
#include<QLabel>
#include<QGridLayout>
#include<QHBoxLayout>
#include<QVBoxLayout>
#include<QPropertyAnimation>
#include<QListView>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
//重写Label类，使其能够支持动画闪烁效果
class MyLabel : public QLabel
{
    Q_OBJECT
    Q_PROPERTY(QColor color READ color WRITE setColor)
public:
    using QLabel::QLabel;
    void setColor (QColor color)
    {
        setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(color.red()).arg(color.green()).arg(color.blue()));
    }
    QColor color()
    {
        return Qt::black; // getter is not really needed for now
    }
};
//页表项
class PageItem : public MyLabel
{
    Q_OBJECT
    using MyLabel::MyLabel;
public:
    PageItem(int pageNum,int memNum,int count)
    {
        this->pageNum=pageNum;
        this->memNum=memNum;
        this->count=count;
    }
    PageItem(){};
    int pageNum;//虚页号
    int memNum;//物理块号
    int count;//LRU算法的计数用的，count值越大表示最近最不常使用
};
//cache项
class CacheItem: public MyLabel
{
    using MyLabel::MyLabel;
public:
    int tag;
    int status;
    QVector<MyLabel*> data;
    CacheItem(int tag,int status)
    {
        this->tag=tag;
        this->status=status;
    }
};
//页表
class Page :public QWidget
{
    using QWidget::QWidget;
public:
    QVector<PageItem *> container;
};
//cache
class Cache:public QWidget
{
    using QWidget::QWidget;
public:
    QVector<CacheItem *> container;
};
//内存&外存
class Mem:public QWidget
{
    using QWidget::QWidget;
public:
    QVector<MyLabel *> container;
};
//主窗口
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    int page_num=8;//物理页面数
    int page_size=2;  //页面大小2^3
    int cache_block_size=2;//cache块大小
    int cache_size=8;//cache大小
    int mem_size=16;//内存大小
    int out_mem_size=16;//设置外存大小和内存一样
    int path_num=1;//组相联路数
    QString algorithm="LRU";//页表替换算法

    int width=76;//内存单元的大小/像素
    int height=27;
    int splash_time=500;
    int move_time=1000;

    int cur_step=1;//当前的步骤编号
    bool isclicked=false;//是否点击了“下一步”
    int cache_index;//cache索引
    int cache_tag;//cache的tag
    int physical_address;//物理地址
    int mem_num;//物理块号
    Page *page;//页表
    Cache *cache;//cache
    Mem *mem,*out_mem;//内存&外存

    QGridLayout *page_layout,*cache_layout;//页表的布局、cache的布局
    void StyleInit();//样式初始化
    void PageTableInit();//页表初始化
    void CacheInit();//cache初始化
    void MemInit();//内存初始化
    void OutMemInit();//外存初始化
    void FirstStepInit();//第一步初始化
    void SecondStepInit();//第二步4个元件的初始化
    void reset_all();//删除四个元件，清空三个地址条
    int locate(int n);//输入虚页号，得物理块号
    int read_cache(int cache_index,int tag);//读cache,tag为物理地址中的tag，返回命中信息
    int LRU(int adr);//LRU页表替换算法
    int MyRandom(int adr);//页表随机替换算法
    QPropertyAnimation* moveAtoB(QLabel *a,QWidget *pa,QLabel *b,QWidget *pb,QWidget *reference,int mode);//移动元件单元项
    //把pa元件中的a移动到pb元件的b位置，统一参考父控件是reference，移动类型是mode
private slots:
    void on_start_clicked();//‘开始转换’

    void on_determine_clicked();//‘确认’

    void on_quit_clicked();//‘退出’

    void on_page_size_comboBox_currentTextChanged(const QString &arg1);//获取页大小

    void on_mem_size_comboBox_currentTextChanged(const QString &arg1);//获取内存大小

    void on_cache_block__size_comboBox_currentTextChanged(const QString &arg1);//获取cache块大小

    void on_cache_sizze_comboBox_currentTextChanged(const QString &arg1);//获取cache大小

    void on_path_num_comboBox_currentTextChanged(const QString &arg1);//获取相联度

    void on_algorithmcomboBox_2_currentTextChanged(const QString &arg1);//获取页表替换算法

    void on_reset_clicked();//‘重置’

    void on_next_step_clicked();//‘下一步’

    void open_setting();//设置界面

    void open_use();//使用说明界面

    void getinfo(int a,int b,int c,int d);//从子界面接收参数

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
